package com.ppt.android.base

import android.annotation.SuppressLint
import android.app.Application
import android.content.Context
import android.util.Log
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStore
import androidx.lifecycle.ViewModelStoreOwner
import com.ppt.android.base.app.LoadModuleProxy
import com.ppt.android.base.http.setHttpClient
import com.ppt.android.base.ktx.setApplicationContext
import com.ppt.android.base.utils.OkHelper
import com.ppt.android.base.utils.PPTSPUtils
import kotlinx.coroutines.*
import kotlin.system.measureTimeMillis

/**
 * Application 基类
 *
 * @author ZouJiaCai
 * @since 4/24/21 5:30 PM
 */
open class BaseApplication : Application(), ViewModelStoreOwner {
    companion object {
        // 全局Context
        @SuppressLint("StaticFieldLeak")
        lateinit var context: Context

        @SuppressLint("StaticFieldLeak")
        lateinit var application: BaseApplication

        @SuppressLint("StaticFieldLeak")
        var isAgree: Boolean = false

        val mCoroutineScope by lazy(mode = LazyThreadSafetyMode.NONE) { MainScope() }
        val mLoadModuleProxy by lazy(mode = LazyThreadSafetyMode.NONE) { LoadModuleProxy() }

        /**
         * 初始化第三方依赖
         */
        fun initDepends() {
            // 开启一个 Default Coroutine 进行初始化不会立即使用的第三方
            mCoroutineScope.launch(Dispatchers.Default) {
                mLoadModuleProxy.initByBackstage()
            }

            // 前台初始化
            val allTimeMillis = measureTimeMillis {
                val depends = mLoadModuleProxy.initByFrontDesk()
                var dependInfo: String
                depends.forEach {
                    val dependTimeMillis = measureTimeMillis { dependInfo = it() }
                    Log.d("BaseApplication", "initDepends: $dependInfo : $dependTimeMillis ms")
                }
            }
            Log.d("BaseApplication", "初始化完成 $allTimeMillis ms")
        }
    }

    // 替换为属性实现
    override val viewModelStore: ViewModelStore by lazy { ViewModelStore() }

    private var mFactory: ViewModelProvider.Factory? = null

    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(base)
        context = base
        application = this
        mLoadModuleProxy.onAttachBaseContext(base)
    }

    override fun onCreate() {
        super.onCreate()
        initHttp()
        isAgree = PPTSPUtils.get("isAgree", false) as Boolean

        mLoadModuleProxy.onCreate(this)
        initDepends()
        setApplicationContext(this) // 设置全局上下文
    }

    fun getAppViewModelProvider(): ViewModelProvider {
        return ViewModelProvider(this, this.getAppFactory())
    }

    private fun getAppFactory(): ViewModelProvider.Factory {
        if (mFactory == null) {
            mFactory = ViewModelProvider.AndroidViewModelFactory.getInstance(this)
        }
        return mFactory as ViewModelProvider.Factory
    }

    override fun onTerminate() {
        super.onTerminate()
        mLoadModuleProxy.onTerminate(this)
        mCoroutineScope.cancel()
    }

    private fun initHttp() {
        setHttpClient(OkHelper.httpClient(applicationContext))
    }
}